package com.framework.common.util;

import com.framework.common.domain.WechatMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhoubb
 * @version V1.0
 * @Date 2020/5/21 23:50
 * @since JDK 1.8
 */
@Slf4j
public class XmlUtil {

    /**
     * 解析request中的xml内容
     * @param request
     * @return
     */
    public static Map<String, String> xmlToMap(HttpServletRequest request) {
        String xml = readRequestContent(request);
        if(StringUtils.isNotBlank(xml)) {
            return xmlToMap(xml);
        }

        return null;
    }

    public static WechatMessage xmlToObject(HttpServletRequest request) {
        String xml = readRequestContent(request);
        if(StringUtils.isNotBlank(xml)) {
            return (WechatMessage)convertToObject(xml, WechatMessage.class);
        }

        return null;
    }

    public static <T> T convertToObject(String xml, Class<T> clazz) {
        T _clazz = null;
        try(StringReader reader = new StringReader(xml)) {
            JAXBContext context = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            _clazz = (T) unmarshaller.unmarshal(reader);
        } catch (Exception e) {
            log.error("xml解析异常", e);
            return null;
        }
        return _clazz;
    }
    /**
     * XML格式字符串转换为Map
     *
     * @param xml XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String xml) {
        try {
            Map<String, String> data = new HashMap<>();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(xml.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            stream.close();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 从request中读取用户发给公众号的消息内容
     * @param request
     * @return 用户发给公众号的消息内容
     * @throws IOException
     */
    public static String readRequestContent(HttpServletRequest request) {
        // 从输入流读取返回内容
        StringBuilder buffer = new StringBuilder();
        try (InputStream inputStream = request.getInputStream();
             InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
             BufferedReader bufferedReader = new BufferedReader(inputStreamReader)){
            String str = null;


            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
        } catch (IOException e) {
            log.error("读取request请求异常", e);
        }

        return buffer.toString();
    }
}
